/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.arif.alg.sulamunnayirain;

import java.util.logging.Logger;

/**
 *
 * @author S Arifin B
 */
 public class Row{
        private int koloms[];
        public int length;
        Logger logger=Logger.getLogger(SulamunNayyirain.class.getName());
        public void convertWith(Row r, int start){
            for(int i=0;i<r.length;i++){
                this.koloms[start+i]=r.koloms[i];
            }
        }
        public void move(int movementTo, boolean isRightToLeft){
            Row tm=new Row(this.length);
            int index=movementTo;                        
            if(isRightToLeft){               
                for(int i=0;index<this.length;i++){
                    tm.koloms[i]=this.koloms[index];
                    index++;
                }                
            }else{                
                for(int i=index;index<this.length;i++){
                    tm.koloms[i]=this.koloms[index-movementTo];
                    index++;
                }
            }
            for(int i=0;i<this.length;i++){
                this.koloms[i]=tm.koloms[i];
            }
        }
        public Row getPerFragment(int start, int length) throws Exception{
            
            Row row=new Row(length);
            int end=start+length;
            
                if(end>this.length || start > this.length){
                    throw  new Exception("Length can't more than "+this.length);
                }
                int index=0;
                for(int i=start;i<end;i++){
                    row.set(index, this.koloms[i]);
                    index++;
                }
            return row;
        }
        
        public Row substract(Row r, int[] limit, boolean isRigthToLeft, int fragment) throws Exception{
        	return this.substract(r, limit, isRigthToLeft, fragment, false);
        }
        
        public Row substract(Row r, int[] limit, boolean isRigthToLeft, int fragment, boolean isHisotussaah) throws Exception{
            if(r.length!=this.length){
                throw new Exception("Column size not same.");
            }
            if(limit.length<=0 || limit.length!=r.length){
                throw new Exception("Limit not set.");
            }            
            if(isHisotussaah){
            	fragment++;
            }
            int start=0;            
            int end =0;
            int lessValue=0;
            Row result=new Row(this.length);
            if(isRigthToLeft){
                start=this.length-1;
                end=0;
                    for(int i=start;i>=end;i--){
                        int tm=this.koloms[i]-lessValue;
                        lessValue=0;     
                        if((i)%fragment!=0){
                        	if(isHisotussaah){
                        		if(tm<=r.koloms[i]){
                                    lessValue=1;
                                    tm+=limit[i];
                                }
                        	}else{
                        		if(tm<r.koloms[i]){
                                    lessValue=1;
                                    tm+=limit[i];
                                }	
                        	}                            
                        }
                        tm=tm-r.koloms[i];
                        if((i)%fragment==0){
                            lessValue=0;
                        }
                        result.koloms[i]=Math.abs(tm);
                    }
            }else{
                start=0;
                end=this.length;
                    for(int i=start;i<end;i++){
                        int tm=this.koloms[i]-lessValue;
                        lessValue=0;     
                        if((i+1)%fragment!=0){
                        	if(isHisotussaah){
                        		if(tm<=r.koloms[i]){
                                    lessValue=1;
                                    tm+=limit[i];
                                }
                        	}else{
                        		if(tm<r.koloms[i]){
                                    lessValue=1;
                                    tm+=limit[i];
                                }	
                        	}                            
                        }                        
                        tm=tm-r.koloms[i];
                        if((i+1)%fragment==0){
                            lessValue=0;
                        }
                        result.koloms[i]=Math.abs(tm);
                    }
            }
            return result;
        }
        
        public Row normalize(int[] limit, boolean isRigthToLeft, int fragment) throws Exception{
            Row r = new Row(this.length);
            return this.add(r, limit, isRigthToLeft, fragment);
        }
        public Row add(Row r, int[] limit, boolean isRigthToLeft, int fragment) throws Exception{
                
                
                if(r.length!=this.length){
                    throw new Exception("Column size not same.");
                }
                if(limit.length<=0 || limit.length!=r.length){
                        throw new Exception("Limit not set.");
                }
                int start=0;            
                int end =0;
                int moreValue=0;
                Row result=new Row(r.length);
                if(isRigthToLeft){
                    start=r.length-1;
                    end=0;
                    for(int i=start;i>=end;i--){
                        int tm=this.koloms[i]+r.koloms[i]+moreValue;
                        moreValue=0;                                          
                        if(i>end-1){
                            if(tm>=limit[i]){
                                moreValue=tm/limit[i];
                                tm=tm%limit[i];
                            }
                            if((i)%fragment==0){
                                moreValue=0;   
                            }                             
                        }else{
                        	if(tm>limit[i]){
                        		tm=tm%limit[i];	
                        	}                            
                        }                        
                        result.koloms[i]=tm;
                    }                    
                }else{
                    start=0;
                    end=r.length;            
                    for(int i=start;i<end;i++){
                        int tm=this.koloms[i]+r.koloms[i]+moreValue;
                        moreValue=0;         
                        if(i<end-1){
                            if(tm>=limit[i]){
                                moreValue=tm/limit[i];
                                tm=tm%limit[i];
                            }
                            if((i+1)%fragment==0){
                                moreValue=0;
                            }
                        }else{
                        	if(tm>limit[i]){
                        		tm=tm%limit[i];	
                        	}                            
                        }
                        result.koloms[i]=tm;
                    }
                }
            return result;
            
        }
        public void set(int index, int value) throws Exception{
            if(index>=0 && index<length){
                koloms[index]=value;    
            }else{
                throw new Exception("stack overflow");
            }
            
        }
        public int get(int index) throws Exception{
            if(index>=0 && index<length){
                return koloms[index];
            }else{
                throw new Exception("stack overflow");
            }
        }
        public Row(int lenth) {
            this.koloms = new int[lenth];            
            this.length=lenth;
            for(int i=0;i<this.length;i++){
                this.koloms[i]=0;
            }
        }
        
    }